package net.tv90.volunteerserveradmin.service;

import jakarta.annotation.Resource;
import jakarta.persistence.criteria.Predicate;
import net.tv90.volunteerserveradmin.dao.OperationLogRepository;
import net.tv90.volunteerserveradmin.dao.UserRepository;
import net.tv90.volunteerserveradmin.exception.ServiceException;
import net.tv90.volunteerserveradmin.model.domain.OperationLog;
import net.tv90.volunteerserveradmin.model.domain.User;
import net.tv90.volunteerserveradmin.model.dto.OperationLogQueryDTO;
import net.tv90.volunteerserveradmin.model.vo.OperationLogVO;
import net.tv90.volunteerserveradmin.utils.entity.PageResult;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class OperationLogService {

    @Resource
    private OperationLogRepository operationLogRepository;

    @Resource
    private UserRepository userRepository;


    public void saveOperationLog(OperationLog operationLog) {
        operationLogRepository.save(operationLog);
    }

    public List<OperationLog> getAllLogs() {
        return operationLogRepository.findAll();
    }

    public OperationLogVO findById(Long id){
        OperationLog operationLog = operationLogRepository.findById(id)
                .orElseThrow(() -> new ServiceException("日志不存在", HttpStatus.OK));
        User user = operationLog.getUserId() != null ?
                userRepository.findById(operationLog.getUserId())
                        .orElse(User.newDeletedUser()) :
                new User(); // 可以返回一个空的用户对象，或者一个默认的游客对象
        return new OperationLogVO(operationLog, user);
    }

    public PageResult<OperationLogVO> queryLogs(OperationLogQueryDTO dto) {
        if (dto.getPage() == null || dto.getPage() < 1) {
            dto.setPage(1);
        }
        if (dto.getPageNum() == null || dto.getPageNum() < 10 || dto.getPageNum() > 100) {
            dto.setPageNum(10);
        }
        if (dto.getOrderBy() == null || dto.getOrderBy().isEmpty()) {
            dto.setOrderBy("id");
        }
        if (dto.getDesc() == null) {
            dto.setDesc(0);
        }

        // 构建排序
        Sort sort = dto.getDesc() == 1 ? Sort.by(dto.getOrderBy()).descending() : Sort.by(dto.getOrderBy()).ascending();
        PageRequest pageRequest = PageRequest.of(dto.getPage() - 1, dto.getPageNum(), sort);

        // 构建 Specification
        Specification<OperationLog> spec = (root, query, criteriaBuilder) -> {
            Predicate predicate = criteriaBuilder.conjunction();

            // 根据用户id精确查询
            if (dto.getUserId() != null && dto.getUserId() > 0) {
                predicate = criteriaBuilder.and(predicate, criteriaBuilder.equal(root.get("userId"), dto.getUserId()));
            }

            // 根据用户名模糊查询
            if (dto.getUsername() != null && !dto.getUsername().isEmpty()) {
                // 先查询符合条件的用户
                List<User> users = userRepository.findByUsernameContaining(dto.getUsername());
                if (!users.isEmpty()) {
                    // 获取所有符合条件的 userId
                    List<Long> userIds = users.stream()
                            .map(User::getId)
                            .collect(Collectors.toList());
                    predicate = criteriaBuilder.and(predicate, root.get("userId").in(userIds));
                } else {
                    // 如果没有符合的用户，则返回空的查询结果
                    predicate = criteriaBuilder.and(predicate, criteriaBuilder.equal(root.get("userId"), -1)); // 一个不存在的 userId
                }
            }

            // 根据操作地址模糊查询
            if (dto.getIpSource() != null && !dto.getIpSource().isEmpty()) {
                predicate = criteriaBuilder.and(predicate, criteriaBuilder.like(root.get("ipSource"), "%" + dto.getIpSource() + "%"));
            }

            // 根据操作耗时范围查询
            if (dto.getStartTimes() != null) {
                predicate = criteriaBuilder.and(predicate, criteriaBuilder.greaterThanOrEqualTo(root.get("times"), dto.getStartTimes()));
            }
            if (dto.getEndTimes() != null && dto.getEndTimes() > 1) {
                predicate = criteriaBuilder.and(predicate, criteriaBuilder.lessThanOrEqualTo(root.get("times"), dto.getEndTimes()));
            }

            // 根据创建时间范围查询
            if (dto.getStartCreateTime() != null) {
                predicate = criteriaBuilder.and(predicate, criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"), dto.getStartCreateTime()));
            }
            if (dto.getEndCreateTime() != null) {
                predicate = criteriaBuilder.and(predicate, criteriaBuilder.lessThanOrEqualTo(root.get("createTime"), dto.getEndCreateTime()));
            }

            return predicate;
        };

        // 调用 Repository 层的 findAll 方法执行查询
        Page<OperationLog> logPage = operationLogRepository.findAll(spec, pageRequest);

        // 将查询结果转换为 OperationLogVO
        List<OperationLogVO> list = logPage.getContent().stream()
                .map(operationLog -> {
                    // 如果用户ID为null，说明是游客，返回一个默认的用户或者空用户
                    User user = operationLog.getUserId() != null ?
                            userRepository.findById(operationLog.getUserId())
                                    .orElse(User.newDeletedUser()) :
                            new User(); // 可以返回一个空的用户对象，或者一个默认的游客对象

                    return new OperationLogVO(operationLog, user);
                })
                .collect(Collectors.toList());
        return new PageResult<>(list, logPage.getTotalElements());
    }
}
